package store

import (
	"encoding/json"
	"fmt"
	"wespy-http-go/app/activity/common/actreward"
	"wespy-http-go/helper"

	"wespy-http-go/app/activity/common/actinfo"
	"wespy-http-go/app/activity/common/actstore"
	"wespy-http-go/app/activity/common/actutil"
)

const (
	kvUserLock        = "act:%d:::user_lock:%d"                         // actId,uid 锁
	kvDrinkCarName    = "act:%d:summer_drink_car:name:%d"               // actId,uid 名称
	hashOpenState     = "act:%d:summer_drink_car:open_state:%d"         // actId,uid 开启状态
	kvNextFlyerTime   = "act:%d:summer_drink_car:next_flyer_time:%d:%s" // actId,uid,day 下一个传单时间
	kvFreeFlyerFlag   = "act:%d:summer_drink_car:free_flyer_flag:%d:%s" // actId,uid,date 是否发送过免费传单消息
	zSetTableEndTime  = "act:%d:summer_drink_car:table_end_time:%d"     // actId,uid 用餐结束时间
	kvWaitNum         = "act:%d:summer_drink_car:wait_num:%d"           // actId,uid 排队数量
	hashCheckoutInfo  = "act:%d:summer_drink_car:checkout_info:%d"      // actId 结账信息
	kvSignLock        = "act:%d:summer_drink_car:sign_lock:%d"          // actId,uid 签到锁
	hashNormalState   = "act:%d:summer_drink_car:normal_state:%d"       // actId,uid 普通签到状态
	hashAdvancedState = "act:%d:summer_drink_car:advanced_state:%d"     // actId,uid 高级签到状态
	kvSignPopup       = "act:%d:summer_drink_car:sign_popup:%d"         // actId,uid 签到弹窗奖励
)

const (
	CheckoutFieldTipNum          = "tip_num"
	CheckoutFieldReputationScore = "reputation_score"
)

func GetUserLockKey(actId, uid int) string {
	return actinfo.WrapKeyWithVersion(actId, fmt.Sprintf(kvUserLock, actId, uid))
}

func GetDrinkCarNameKey(actId, uid int) string {
	return actinfo.WrapKeyWithVersion(actId, fmt.Sprintf(kvDrinkCarName, actId, uid))
}

func GetDrinkCarName(actId, uid int) (string, error) {
	return actstore.Get(GetDrinkCarNameKey(actId, uid))
}

func SetDrinkCarName(actId, uid int, name string) error {
	return actstore.Set(GetDrinkCarNameKey(actId, uid), name, actutil.GetTotalTTL(actId))
}

func GetOpenStateKey(actId, uid int) string {
	return actinfo.WrapKeyWithVersion(actId, fmt.Sprintf(hashOpenState, actId, uid))
}

func GetOpenState(actId, uid int, day string) (int, error) {
	return actstore.HGetInt(GetOpenStateKey(actId, uid), day)
}

func SetOpenState(actId, uid int, day string, state int) error {
	return actstore.HSet(GetOpenStateKey(actId, uid), day, state, actutil.GetTotalTTL(actId))
}

func GetNextFlyerTimeKey(actId, uid int, day string) string {
	return actinfo.WrapKeyWithVersion(actId, fmt.Sprintf(kvNextFlyerTime, actId, uid, day))
}

func SetNextFlyerTime(actId, uid int, day string, timestamp int) error {
	return actstore.Set(GetNextFlyerTimeKey(actId, uid, day), timestamp, actutil.GetTotalTTL(actId))
}

func GetNextFlyerTime(actId, uid int, day string) (int, error) {
	return actstore.GetInt(GetNextFlyerTimeKey(actId, uid, day))
}

func getFreeFlyerFlagKey(actId, uid int, date string) string {
	return actinfo.WrapKeyWithVersion(actId, fmt.Sprintf(kvFreeFlyerFlag, actId, uid, date))
}

func IncrFreeFlyerFlag(actId, uid int, date string) (int, error) {
	return actstore.IncrBy(getFreeFlyerFlagKey(actId, uid, date), 1, actutil.GetTotalTTL(actId))
}

// 营业顾客相关函数

func getZSetTableEndTimeKey(actId, uid int) string {
	return actinfo.WrapKeyWithVersion(actId, fmt.Sprintf(zSetTableEndTime, actId, uid))
}

func GetTableNum(actId, uid int) (int, error) {
	return actstore.ZCard(getZSetTableEndTimeKey(actId, uid))
}

func AddTable(actId, uid int, dataMap map[int]int) error {
	if len(dataMap) == 0 {
		return nil
	}
	args := make([]interface{}, 0)
	for k, v := range dataMap {
		args = append(args, v, k)
	}
	return actstore.ZAddMulti(getZSetTableEndTimeKey(actId, uid), actutil.GetTotalTTL(actId), args...)
}

func GetTableList(actId, uid, start, end int) ([]*TableInfoDTO, error) {
	memberID, endTimes, err := actstore.ZRangeInt(getZSetTableEndTimeKey(actId, uid), start, end)
	if err != nil {
		return nil, err
	}
	tableInfoList := make([]*TableInfoDTO, 0, len(endTimes))
	for index, endTime := range endTimes {
		tableInfoList = append(tableInfoList, &TableInfoDTO{
			Timestamp: endTime,
			Member:    memberID[index],
		})
	}
	return tableInfoList, nil
}

func GetEndedTable(actId, uid int, timestamp int) ([]int, error) {
	memberString, _, err := actstore.ZRangeByScore(getZSetTableEndTimeKey(actId, uid), "-inf", timestamp, 0, 100)
	if err != nil {
		return make([]int, 0), err
	}
	members := helper.ConvertStringSlice2IntSlice(memberString)
	return members, nil
}

func DelUserInTable(actId, uid int, uidList []int) error {
	args := make([]interface{}, 0)
	for _, v := range uidList {
		args = append(args, v)
	}
	return actstore.ZRemMulti(getZSetTableEndTimeKey(actId, uid), actutil.GetTotalTTL(actId), args...)
}

func getWaitQueue(actId, uid int) string {
	return actinfo.WrapKeyWithVersion(actId, fmt.Sprintf(kvWaitNum, actId, uid))
}

func IncrWaitNum(actId, uid, value int) (int, error) {
	return actstore.IncrBy(getWaitQueue(actId, uid), value, actutil.GetTotalTTL(actId))
}

func DeductWaitNum(actId, uid, value int) (int, error) {
	return actstore.IncrBy(getWaitQueue(actId, uid), -value, actutil.GetTotalTTL(actId))
}

func GetWaitNum(actId, uid int) (int, error) {
	return actstore.GetInt(getWaitQueue(actId, uid))
}

func DelWaitNum(actId, uid int) error {
	return actstore.Del(getWaitQueue(actId, uid))
}

func getCheckoutInfoKey(actId, uid int) string {
	return actinfo.WrapKeyWithVersion(actId, fmt.Sprintf(hashCheckoutInfo, actId, uid))
}

func GetCheckoutInfo(actId, uid int) (map[string]int, error) {
	return actstore.HGetAllStringIntMap(getCheckoutInfoKey(actId, uid))
}

func IncrCheckoutInfoField(actId, uid int, field string, value int) (int, error) {
	return actstore.HIncrBy(getCheckoutInfoKey(actId, uid), field, value, actutil.GetTotalTTL(actId))
}

func ClearCheckoutInfo(actId, uid int) error {
	return actstore.Del(getCheckoutInfoKey(actId, uid))
}

// 签到相关函数

func GetSignLockKey(actId, uid int) string {
	return actinfo.WrapKeyWithVersion(actId, fmt.Sprintf(kvSignLock, actId, uid))
}

func GetNormalStateKey(actId, uid int) string {
	return actinfo.WrapKeyWithVersion(actId, fmt.Sprintf(hashNormalState, actId, uid))
}

func SetNormalState(actId, uid int, day string, state int) error {
	return actstore.HSet(GetNormalStateKey(actId, uid), day, state, actutil.GetTotalTTL(actId))
}

func GetNormalStateMap(actId, uid int) (map[string]int, error) {
	return actstore.HGetAllStringIntMap(GetNormalStateKey(actId, uid))
}

func GetAdvancedStateKey(actId, uid int) string {
	return actinfo.WrapKeyWithVersion(actId, fmt.Sprintf(hashAdvancedState, actId, uid))
}

func SetAdvancedState(actId, uid int, day string, state int) error {
	return actstore.HSet(GetAdvancedStateKey(actId, uid), day, state, actutil.GetTotalTTL(actId))
}

func GetAdvancedStateMap(actId, uid int) (map[string]int, error) {
	return actstore.HGetAllStringIntMap(GetAdvancedStateKey(actId, uid))
}

func getSignPopupKey(actId, uid int) string {
	return actinfo.WrapKeyWithVersion(actId, fmt.Sprintf(kvSignPopup, actId, uid))
}

func SetSignPopup(actId, uid int, rewards []*actreward.RewardInfo) error {
	return actstore.SetEx(getSignPopupKey(actId, uid), helper.GetString(rewards), actutil.GetTotalTTL(actId))
}

func GetSignPopup(actId, uid int) ([]*actreward.RewardInfo, error) {
	data, err := actstore.Get(getSignPopupKey(actId, uid))
	if err != nil {
		return nil, err
	}
	rsp := make([]*actreward.RewardInfo, 0)
	if data == "" {
		return rsp, nil
	}
	err = json.Unmarshal([]byte(data), &rsp)
	if err != nil {
		return nil, err
	}
	return rsp, nil
}

func ClearSignPopup(actId, uid int) error {
	return actstore.Del(getSignPopupKey(actId, uid))
}
